package com.ocp.socket.server.service;

import com.alibaba.fastjson.JSON;
import com.ocp.socket.busi.dataMilkUtils.bean.DataMilkVo;
import com.ocp.socket.busi.dataMilkUtils.bean.QueryDataMilkVo;
import com.ocp.socket.busi.dataMilkUtils.mapper.DataMilkUtilsMapper;
import com.ocp.socket.busi.dataTempUtils.bean.DataTempVo;
import com.ocp.socket.busi.dataTempUtils.mapper.DataTempUtilsMapper;
import com.ocp.socket.busi.utils.mapper.UtilsMapper;
import com.ocp.socket.busi.utils.service.IDataUtilService;
import com.ocp.socket.busi.warnItem.bean.BaseWarnItem;
import com.ocp.socket.busi.warnItem.mapper.BaseWarnItemMapper;
import com.ocp.socket.busi.warnMsg.bean.BaseWarnMsg;
import com.ocp.socket.busi.warnMsg.mapper.BaseWarnMsgMapper;
import com.ocp.socket.common.Constants;
import com.ocp.socket.common.bean.DevInfo;
import com.ocp.socket.common.enums.DeviceWarnEnum;
import com.ocp.socket.common.enums.MsgTypeEnum;
import com.ocp.socket.common.enums.WarnCodeEnum;
import com.ocp.socket.common.utils.CommonUtils;
import com.ocp.socket.common.utils.RedisUtil;
import com.ocp.socket.common.utils.SessionUtil;
import com.ocp.socket.common.utils.TableUtils;
import com.ocp.socket.server.vo.DataVo;
import com.ocp.socket.server.vo.MessageVo;
import org.apache.mina.core.session.IoSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Auther: zhangzh
 * @Date: 2019/3/3 07:01
 * @Description: 温度报文处理
 * @Version: 1.0.0
 */
@Service("tempService")
@Transactional
public class TempService {
    private static final Logger logger = LoggerFactory.getLogger(TempService.class);

    @Value("${msgDataDb}")
    private String msgDataDb;

    @Value("${tempMsg}")
    private String temp;

    @Value("${milkMsg}")
    private String milk;

    @Autowired
    UtilsMapper utilsMapper;

    @Autowired
    DataMilkUtilsMapper dataMilkUtilsMapper;

    @Autowired
    DataTempUtilsMapper dataTempUtilsMapper;

    @Autowired
    BaseWarnMsgMapper baseWarnMsgMapper;

    @Autowired
    BaseWarnItemMapper baseWarnItemMapper;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private IDataUtilService dataUtilService;


    /******
     * 保存温度的报文信息到数据库
     * @param messageVo
     * @return
     */
    public MessageVo saveTemperatureData(MessageVo messageVo, IoSession session) {
        if (messageVo.getDataVoMap().size() < 1) {
            logger.info("当前温度没有配置线路！");
            messageVo.setReturnCode("1");
            messageVo.setReturnMsg("当前温度没有配置线路！");
            return messageVo;
        }
        //获取设备信息
        DevInfo devInfo = (DevInfo) session.getAttribute(Constants.ATTRIBUTE_KEY_AUTH);
        //牧场的id
        Integer orgId = devInfo.getOrgId();
        //当前温度记录表
        String nowTempTableName = TableUtils.getDataTableName(msgDataDb, temp, orgId, messageVo.getDataTime().substring(0, 8));
        //温度状态表
        String tempStatTableName = TableUtils.getDataStatTableName(temp, orgId);
        //挤奶清洗状态当前状态表
        String milkStatTableName = TableUtils.getDataStatTableName(milk, orgId);
        //创建温度记录表
        dataUtilService.createDataTableIfNotExist(nowTempTableName, temp);
        //创建当前温度表状态表
        dataUtilService.createStatTableIfNotExist(tempStatTableName, temp);
        //创建当前挤奶清洗状态表
        dataUtilService.createStatTableIfNotExist(milkStatTableName, milk);
        //报警信息MAP
        Map<String, String> baseWarnMsgMap = new HashMap<String, String>();
        //报警信息稳定时长MAP
        Map<String, Integer> baseWarnMsgTimesMap = new HashMap<String, Integer>();
        //报警项信息MAP
        Map<String, BaseWarnItem> baseWarnItemMap = new HashMap<String, BaseWarnItem>();

        //根据奶厅查询当前奶厅挤奶清洗的状态
        QueryDataMilkVo queryDataMilkVo = new QueryDataMilkVo();
        queryDataMilkVo.setHallId(devInfo.getHallId());
        queryDataMilkVo.setVal("-1");
        DataMilkVo dataMilkVo = dataMilkUtilsMapper.getInfoByTableName(milkStatTableName.toString(), queryDataMilkVo);
        //旧数据
        if (!messageVo.isNewDataFlag()) {
            Map<String, DataVo> dataVoMap = messageVo.getDataVoMap();
            List<DataTempVo> datas = new ArrayList<>();
            DataTempVo dataTempVo = null;
            DataVo dataVo;
            for (String key : dataVoMap.keySet()) {
                dataVo = dataVoMap.get(key);
                dataTempVo = new DataTempVo();
                dataTempVo.setHallId(devInfo.getHallId());
                dataTempVo.setDataTime(messageVo.getDataTime());
                dataTempVo.setLineCode(key);
                dataTempVo.setVal(Double.valueOf(dataVo.getVal()));
                dataTempVo.setUnit("℃");
                dataTempVo.setRunStat(dataVo.getRunStat());
                dataTempVo.setRunStatDesc(dataVo.getRunStatDesc());
                dataTempVo.setSnNo(messageVo.getSn());
                datas.add(dataTempVo);
            }
            try {
                dataTempUtilsMapper.insertDataTemps(nowTempTableName, datas);
            } catch (Exception e) {
                logger.error("批量插入温度数据报错:{}", e.getMessage());
            }
            return messageVo;
        }
        //奶厅下已有且未结束的报警信息
        List<BaseWarnMsg> baseWarnMsgList = baseWarnMsgMapper.getBaseWarnMsgListByMilkHallId(devInfo.getHallId());
        for (BaseWarnMsg baseWarnMsg : baseWarnMsgList) {
            baseWarnMsgMap.put(baseWarnMsg.getWarnCode(), baseWarnMsg.getId());
            baseWarnMsgTimesMap.put(baseWarnMsg.getWarnCode(), baseWarnMsg.getEndTimes());
        }
        baseWarnMsgList.clear();

        //根据奶厅查询已配置的报警信息项
        List<BaseWarnItem> baseWarnItemList = baseWarnItemMapper.getBaseWarnItemListByMilkHallId(devInfo.getHallId());
        for (BaseWarnItem baseWarnItem : baseWarnItemList) {
            baseWarnItemMap.put(baseWarnItem.getWarnCode(), baseWarnItem);
        }
        baseWarnItemList.clear();

        /****
         * W001 牛奶预冷后温度高
         * 奶厅已配置该报警
         * 报警关键因素 T1温度和T2温度
         */
        if (baseWarnItemMap.get(WarnCodeEnum.W001.getWarnCode()) != null && messageVo.getDataVoMap().get("L01") != null && messageVo.getDataVoMap().get("L02") != null) {
            Double t1Val = Double.valueOf(messageVo.getDataVoMap().get("L01").getVal());
            Double t2Val = Double.valueOf(messageVo.getDataVoMap().get("L02").getVal());
            //挤奶 并且超过20分钟
            if (dataMilkVo != null && "L01".equals(dataMilkVo.getLineCode()) && baseWarnItemMap.get(WarnCodeEnum.W001.getWarnCode()).getIgnoreTimes() < dataMilkVo.getRunTimes()) {
                if (t1Val - t2Val < baseWarnItemMap.get(WarnCodeEnum.W001.getWarnCode()).getMinVal()) {
                    if (baseWarnMsgMap.get(WarnCodeEnum.W001.getWarnCode()) == null) {
                        CommonUtils.insertBaseWarnMsg(session, baseWarnMsgMapper, WarnCodeEnum.W001.getWarnCode(), baseWarnItemMap, messageVo, devInfo, messageVo.getSn(), "L01", redisUtil,DeviceWarnEnum.TEMP.getDeviceCode());
                    } else {
                        baseWarnMsgMapper.initWarnMsgEndTimes(baseWarnMsgMap.get(WarnCodeEnum.W001.getWarnCode()));
                    }
                } else {
                    if (baseWarnMsgMap.get(WarnCodeEnum.W001.getWarnCode()) != null) {
                        if (baseWarnMsgTimesMap !=null && baseWarnMsgTimesMap.get(WarnCodeEnum.W001.getWarnCode()) > 10) {
                            CommonUtils.updateBaseWarnMsgEndTimeById(session, baseWarnMsgMapper, baseWarnMsgMap.get(WarnCodeEnum.W001.getWarnCode()), messageVo.getDataTime(), devInfo.getSnNo(), devInfo.getOrgId());
                        } else {
                            baseWarnMsgMapper.addWarnMsgEndTimes(baseWarnMsgMap.get(WarnCodeEnum.W001.getWarnCode()));
                        }
                    }
                }
            }
        }

        /****
         * W002 平衡罐内奶温异常
         * 奶厅已配置该报警
         * 报警关键因素 T1温度
         */
        if (baseWarnItemMap.get(WarnCodeEnum.W002.getWarnCode()) != null && messageVo.getDataVoMap().get("L01") != null) {
            Double t1Val = Double.valueOf(messageVo.getDataVoMap().get("L01").getVal());
            //挤奶 并且超过20分钟
            if (dataMilkVo != null && "L01".equals(dataMilkVo.getLineCode()) && baseWarnItemMap.get(WarnCodeEnum.W002.getWarnCode()).getIgnoreTimes() < dataMilkVo.getRunTimes()) {
                if (t1Val < baseWarnItemMap.get(WarnCodeEnum.W002.getWarnCode()).getMinVal() || t1Val > baseWarnItemMap.get(WarnCodeEnum.W002.getWarnCode()).getMaxVal()) {
                    messageVo.getDataVoMap().get("L01").setRunStat("0");
                    messageVo.getDataVoMap().get("L01").setRunStatDesc("运行异常");
                    if (baseWarnMsgMap.get(WarnCodeEnum.W002.getWarnCode()) == null) {
                        CommonUtils.insertBaseWarnMsg(session, baseWarnMsgMapper, WarnCodeEnum.W002.getWarnCode(), baseWarnItemMap, messageVo, devInfo, messageVo.getSn(), "L01", redisUtil,DeviceWarnEnum.TEMP.getDeviceCode());
                    } else {
                        baseWarnMsgMapper.initWarnMsgEndTimes(baseWarnMsgMap.get(WarnCodeEnum.W002.getWarnCode()));
                    }
                } else {
                    if (baseWarnMsgMap.get(WarnCodeEnum.W002.getWarnCode()) != null) {
                        if (baseWarnMsgTimesMap !=null && baseWarnMsgTimesMap.get(WarnCodeEnum.W002.getWarnCode()) > 10) {
                            CommonUtils.updateBaseWarnMsgEndTimeById(session, baseWarnMsgMapper, baseWarnMsgMap.get(WarnCodeEnum.W002.getWarnCode()), messageVo.getDataTime(), devInfo.getSnNo(), devInfo.getOrgId());
                        } else {
                            baseWarnMsgMapper.addWarnMsgEndTimes(baseWarnMsgMap.get(WarnCodeEnum.W002.getWarnCode()));
                        }

                    }
                }
            }
        }

        /****
         * W003 牛奶即冷后温度高
         * 奶厅已配置该报警
         * 报警关键因素 T3温度
         */
        if (baseWarnItemMap.get(WarnCodeEnum.W003.getWarnCode()) != null && messageVo.getDataVoMap().get("L03") != null) {
            Double t3Val = Double.valueOf(messageVo.getDataVoMap().get("L03").getVal());
            //挤奶 并且超过20分钟
            if (dataMilkVo != null && "L01".equals(dataMilkVo.getLineCode()) && baseWarnItemMap.get(WarnCodeEnum.W003.getWarnCode()).getIgnoreTimes() < dataMilkVo.getRunTimes()) {
                if (t3Val > baseWarnItemMap.get(WarnCodeEnum.W003.getWarnCode()).getMaxVal()) {
                    messageVo.getDataVoMap().get("L03").setRunStat("0");
                    messageVo.getDataVoMap().get("L03").setRunStatDesc("运行异常");
                    if (baseWarnMsgMap.get(WarnCodeEnum.W003.getWarnCode()) == null) {
                        CommonUtils.insertBaseWarnMsg(session, baseWarnMsgMapper, WarnCodeEnum.W003.getWarnCode(), baseWarnItemMap, messageVo, devInfo, messageVo.getSn(), "L03", redisUtil,DeviceWarnEnum.TEMP.getDeviceCode());
                    } else {
                        baseWarnMsgMapper.initWarnMsgEndTimes(baseWarnMsgMap.get(WarnCodeEnum.W003.getWarnCode()));
                    }
                } else {
                    if (baseWarnMsgMap.get(WarnCodeEnum.W003.getWarnCode()) != null) {
                        if (baseWarnMsgTimesMap !=null && baseWarnMsgTimesMap.get(WarnCodeEnum.W003.getWarnCode()) > 10) {
                            CommonUtils.updateBaseWarnMsgEndTimeById(session, baseWarnMsgMapper, baseWarnMsgMap.get(WarnCodeEnum.W003.getWarnCode()), messageVo.getDataTime(), devInfo.getSnNo(), devInfo.getOrgId());
                        } else {
                            baseWarnMsgMapper.addWarnMsgEndTimes(baseWarnMsgMap.get(WarnCodeEnum.W003.getWarnCode()));
                        }

                    }
                }
            }
        }

        /****
         * W004 预冷水温度过高
         * 奶厅已配置该报警
         * 报警关键因素 T4温度
         */
        if (baseWarnItemMap.get(WarnCodeEnum.W004.getWarnCode()) != null && messageVo.getDataVoMap().get("L04") != null) {
            Double t4Val = Double.valueOf(messageVo.getDataVoMap().get("L04").getVal());
            //挤奶 并且超过20分钟
            if (dataMilkVo != null && "L01".equals(dataMilkVo.getLineCode()) && baseWarnItemMap.get(WarnCodeEnum.W004.getWarnCode()).getIgnoreTimes() < dataMilkVo.getRunTimes()) {
                if (t4Val > baseWarnItemMap.get(WarnCodeEnum.W004.getWarnCode()).getMaxVal()) {
                    messageVo.getDataVoMap().get("L04").setRunStat("0");
                    messageVo.getDataVoMap().get("L04").setRunStatDesc("运行异常");
                    if (baseWarnMsgMap.get(WarnCodeEnum.W004.getWarnCode()) == null) {
                        CommonUtils.insertBaseWarnMsg(session, baseWarnMsgMapper, WarnCodeEnum.W004.getWarnCode(), baseWarnItemMap, messageVo, devInfo, messageVo.getSn(), "L04", redisUtil,DeviceWarnEnum.TEMP.getDeviceCode());
                    } else {
                        baseWarnMsgMapper.initWarnMsgEndTimes(baseWarnMsgMap.get(WarnCodeEnum.W004.getWarnCode()));
                    }
                } else {
                    if (baseWarnMsgMap.get(WarnCodeEnum.W004.getWarnCode()) != null) {
                        if (baseWarnMsgTimesMap !=null && baseWarnMsgTimesMap.get(WarnCodeEnum.W004.getWarnCode()) > 10) {
                            CommonUtils.updateBaseWarnMsgEndTimeById(session, baseWarnMsgMapper, baseWarnMsgMap.get(WarnCodeEnum.W004.getWarnCode()), messageVo.getDataTime(), devInfo.getSnNo(), devInfo.getOrgId());
                        } else {
                            baseWarnMsgMapper.addWarnMsgEndTimes(baseWarnMsgMap.get(WarnCodeEnum.W004.getWarnCode()));
                        }
                    }
                }
            }
        }
        Map<String, DataVo> dataVoMap = messageVo.getDataVoMap();
        DataTempVo dataTempVo = null;
        List<DataTempVo> returnValList = new ArrayList<DataTempVo>();
        DataVo dataVo;
        for (String key : dataVoMap.keySet()) {
            dataVo = dataVoMap.get(key);
            //添加温度报警
            addTempMsgOpenShortWarn(key, Double.valueOf(dataVo.getVal()), messageVo, devInfo, baseWarnItemMap, baseWarnMsgMap, baseWarnMsgTimesMap, session);
            dataTempVo = new DataTempVo();
            dataTempVo.setHallId(devInfo.getHallId());
            dataTempVo.setDataTime(messageVo.getDataTime());
            dataTempVo.setLineCode(key);
            if (dataMilkVo != null) {
                dataTempVo.setMilkCleanLine(dataMilkVo.getLineCode());
            }
            dataTempVo.setVal(Double.valueOf(dataVo.getVal()));
            dataTempVo.setUnit("℃");
            dataTempVo.setRunStat(dataVo.getRunStat());
            dataTempVo.setRunStatDesc(dataVo.getRunStatDesc());
            dataTempVo.setSnNo(messageVo.getSn());
            returnValList.add(dataTempVo);
        }
        try {
            //批量添加数据到数据表
            dataTempUtilsMapper.insertDataTemps(nowTempTableName, returnValList);
        } catch (Exception e) {
            logger.error("批量插入温度数据报错:{}", e.getMessage());
        }
        //处理状态表的数据,先删除再插入数据
        dataTempUtilsMapper.delStatTempData(tempStatTableName, devInfo.getHallId());
        dataTempUtilsMapper.insertDataTemps(tempStatTableName, returnValList);
        //发送消息
        logger.debug("温度发送app的Json:" + JSON.toJSON(returnValList).toString());
        SessionUtil.sendAppUserMsgByOrgId(session, devInfo.getOrgId(), CommonUtils.toMsg(MsgTypeEnum.D.getTypeCode(), messageVo.getSn(), messageVo.getDataTime(), JSON.toJSON(returnValList).toString()));
        returnValList.clear();
        //发送该牧场的报警总数
        Map<String, Integer> warnCntMap = new HashMap<String, Integer>();
        warnCntMap.put("orgWarnCnt", baseWarnMsgMapper.getWarnMsgCntByMilkOrgId(devInfo.getOrgId()));
        SessionUtil.sendAppUserMsgByOrgId(session, devInfo.getOrgId(), CommonUtils.toMsg(MsgTypeEnum.J.getTypeCode(), messageVo.getSn(), messageVo.getDataTime(), JSON.toJSON(warnCntMap).toString()));
        return messageVo;
    }

    /*******
     * 添加温度报警
     * @param lineCode
     * @param val
     * @param messageVo
     * @param devInfo
     * @param baseWarnItemMap
     * @param baseWarnMsgMap
     * @param baseWarnMsgTimesMap
     * @param session
     */
    private void addTempMsgOpenShortWarn(String lineCode, Double val, MessageVo messageVo, DevInfo devInfo, Map<String, BaseWarnItem> baseWarnItemMap, Map<String, String> baseWarnMsgMap, Map<String, Integer> baseWarnMsgTimesMap, IoSession session) {
        String warnCode = null;
        if ("L01".equals(lineCode)) {
            warnCode = "W038";
        } else if ("L02".equals(lineCode)) {
            warnCode = "W039";
        } else if ("L03".equals(lineCode)) {
            warnCode = "W040";
        } else if ("L04".equals(lineCode)) {
            warnCode = "W041";
        } else if ("L05".equals(lineCode)) {
            warnCode = "W042";
        } else if ("L06".equals(lineCode)) {
            warnCode = "W043";
        } else if ("L07".equals(lineCode)) {
            warnCode = "W044";
        } else if ("L08".equals(lineCode)) {
            warnCode = "W045";
        } else if ("L09".equals(lineCode)) {
            warnCode = "W046";
        } else if ("L10".equals(lineCode)) {
            warnCode = "W047";
        } else if ("L11".equals(lineCode)) {
            warnCode = "W048";
        } else if ("L12".equals(lineCode)) {
            warnCode = "W049";
        } else if ("L13".equals(lineCode)) {
            warnCode = "W050";
        }
        if (baseWarnItemMap != null && baseWarnItemMap.get(warnCode) != null && (val > baseWarnItemMap.get(warnCode).getMaxVal() || val < baseWarnItemMap.get(warnCode).getMinVal())) {
            messageVo.getDataVoMap().get(lineCode).setRunStat("0");
            messageVo.getDataVoMap().get(lineCode).setRunStatDesc("运行异常");
            if (baseWarnMsgMap.get(warnCode) == null) {
                CommonUtils.insertBaseWarnMsg(session, baseWarnMsgMapper, warnCode, baseWarnItemMap, messageVo, devInfo, messageVo.getSn(), lineCode, redisUtil,DeviceWarnEnum.TEMP.getDeviceCode());
            } else {
                baseWarnMsgMapper.initWarnMsgEndTimes(baseWarnMsgMap.get(warnCode));
            }
        } else {
            if (baseWarnMsgMap.get(warnCode) != null) {
                if (baseWarnMsgTimesMap !=null && baseWarnMsgTimesMap.get(warnCode) > 10) {
                    CommonUtils.updateBaseWarnMsgEndTimeById(session, baseWarnMsgMapper, baseWarnMsgMap.get(warnCode), messageVo.getDataTime(), devInfo.getSnNo(), devInfo.getOrgId());
                } else {
                    baseWarnMsgMapper.addWarnMsgEndTimes(baseWarnMsgMap.get(warnCode));
                }
            }
        }
    }
}
